package com.xuyuan.agent.jdk;

import com.xuyuan.agent.intro.OrderService;
import com.xuyuan.agent.intro.OrderServiceImpl;
import com.xuyuan.agent.intro.ProxyOrderService;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * 代理对象 实现 InvocationHandler
 * InvocationHandler 该类做方法拦截所用, 通过此类可以对目标方法进行增强
 */
public class JDKProxyDynamic implements InvocationHandler, Serializable {

    private static final long serialVersionUID = 4431939583048226878L;
    private Object target;

    private Class<?> clazz;

    public JDKProxyDynamic(Class<?> clazz) {
        this.clazz = clazz;
    }

    /**
     * 通过该方法的调用对目标对象进行增强
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // debug加上方法名看看调用的是什么
        System.out.println("调度真实对象之前，方法名： " + method.getName() + "，参数：" + args);

        // Spring框架中使用动态代理，可以从applicationContext里面获取对应的target对象
        if (Objects.isNull(target)) {
            target = clazz.newInstance();
        }
        System.out.println("代理前置处理 ...");
        Object returnResult = method.invoke(target, args);
        System.out.println("代理后置处理 ...");
        return returnResult;
    }

    public static void main(String[] args) {
        // 创建动态代理对象,JDK动态代理只能代理实现接口的类
        OrderService proxyInstance = (OrderService) Proxy.newProxyInstance(
                OrderServiceImpl.class.getClassLoader(),
                OrderServiceImpl.class.getInterfaces(),
                new JDKProxyDynamic(OrderServiceImpl.class)
        );

        // 通过代理对象调用方法
        proxyInstance.save();
    }
}